Rv64 m0 substrate - #38
Merged
Merged
Conversation
Phase 1 planning artifacts, produced before any RTL change: - docs/rv64/xlen_audit.md: point-in-time audit of main@9b76e39 - 365 file:line findings across RTL, verif, tests, sw, linux, and fpga (106 silent-misbehavior hazards, 104 design, 31 policy, 124 mechanical), three adversarially-verified readiness claims, and empirical tool-behavior results (zero-width replication accepted by every pinned tool; container gcc is rv64-capable; Spike absent from the image; rv64 arch-test references collide with rv32 goldens today). Headline correction to the roadmap premise: FLD/FSD do not imply an 8-byte memory path. The tier below the queues is 32-bit per transaction (two-phase FSMs, word-granular AMO/reservation, lo/hi CLINT), so a native 64-bit data tier is Phase 1 scope - and a phased 64-bit read of the rolling mtime would tear, so it is not optional. - docs/rv64/phase1_plan.md: strategy, decisions D1-D15, milestones M0-M8 with acceptance gates. Spine: XLEN behind a FROST_RV64 build define with the package as single source of truth; the 64-bit data tier lands first and is proven under the rv32 suites; addresses are canonicalized to the sub-4-GiB map at producers (signature-safe vs Spike because suite code forms addresses PC-relatively - argument recorded in D3); dual-XLEN CI through the phase with the keep/freeze decision measured at exit; Spike pinned into the container; mstatus.FS gets a real implementation including the FS=Off trap (the pinned kernel's fstate_save keys on trap-time FS==Dirty, and the machine-mode csr test requires Off to trap or suppress). Load-bearing decisions were cross-checked by independent review against the vendored kernel, Buildroot, and test-suite sources; the review confirmed the FS mechanism and the rv64-nommu BINFMT_FLAT userspace path, and sharpened D3's conformance argument. - ROADMAP.md: Phase 0 marked done; Phase 1 marked current, with the audit's data-tier correction folded into its premise and pointers to the new docs.
…s, D3 masks Behavior-preserving parameterization pass over the Phase 1 audit's hazard inventory (docs/rv64/xlen_audit.md), all provably bit-identical at rv32: - riscv_pkg: XLEN selected by the FROST_RV64 build define (plan D1); interrupt causes rebuilt XLEN-wide with the mcause interrupt bit at XLEN-1; exception causes widened; XLEN-wide DIV/REM special-case constants (SignedIntMin/SignedIntMax/UnsignedIntMax/NegativeOne) replacing the 32-bit-only forms; from_id_to_ex_t immediates widened to [XLEN-1:0] (D5); physical-map constants + canonical_paddr() (D3). - Sign-extension replication counts made XLEN-relative in immediate_decoder (all five formats; U-type gains the RV64 bit-31 replication) and pd_stage's two redirect immediates - the audit's highest-blast-radius silent-hazard class. - D3 producer canonicalization: PC flops (pc_controller), resolved branch/JALR targets (branch_jump_unit), trap/mret redirect (trap_unit), and all eight store/issue AGU adder outputs. Identity at rv32; at XLEN=64 they pin bits [63:32] of fetch/memory addresses to zero so downstream PC/address state stays sub-4-GiB and synthesis sweeps the upper bits. - Region decodes moved to fixed physical bits: if_stage's served-window guard (bit 31 via CachedRegionBit - [XLEN-1] goes dead at 64 and would resurrect the workqueue_init_early desync class) and lq_l0_cache's MMIO quadrant decode plus its formal properties. - Module XLEN parameter defaults follow riscv_pkg::XLEN (24 modules) so standalone unit benches cannot diverge from the package; cpu_and_mem.f reorders cached_tier_adapter after the package (Yosys resolves package references in parameter defaults only if the package parses first). - Elaboration-legality fixes for XLEN=64 with identical rv32 netlists: int-parameter part-selects become XLEN'() casts (load_queue, request router), [FLEN-1:XLEN] null ranges become shifts (load_queue, sq_forwarding_unit), fp_convert's FMV move slice gains a min-width guard, alu/branch_jump_unit immediate ports widen with the struct fields, instruction_type_decoder compares against '0. - cpu_tb taps re-expressed via riscv_pkg::XLEN; FROST_XILINX_PRIMS FDRE loop bound by $bits; retire-trace format XLEN-selected (rv32 output byte-identical). Gate: hello_world, coremark, directed_traps, c_ext_test, umode_test, reservation_station, pd_stage, id_stage, if_stage pass at rv32; Yosys generic passes at rv32. With FROST_RV64=1 the full tree compiles under Verilator with warnings only (all mapping to audit-known Phase 1 work sites) and passes Yosys generic coarse synthesis end to end.
- tests/Makefile: FROST_RV64=1 adds -DFROST_RV64 to the Verilator build; test_run_yosys.py mirrors it for every Yosys target, keyed on the same environment variable. The formal (.sby) and Vivado entry points gain the define when their milestones first need a 64-bit build (M5/M8 in docs/rv64/phase1_plan.md). - verif/config.py becomes the Python-side single source of width truth: XLEN derives from the same FROST_RV64 environment variable (FLEN added alongside), so the reference models and struct packers flip in lockstep with the RTL. The 20 private "XLEN = 32" copies in cocotb interface/model/test files now import from config - a divergent copy can no longer silently misalign the hand-packed DUT struct layouts when the width changes.
Interface contract for the 64-bit single-beat data tier (plan D2/M1): aligned-dword bus view with 8-lane strobes and replication-based write positioning; dmem as one 64-bit BRAM with a new sw64.mem init (image and loader formats stay 32-bit-word); CLINT gains single-copy-atomic 64-bit mtime/mtimecmp access with the lo/hi aliases preserved; LQ/SQ two-phase FLD/FSD machinery is deleted (single-beat doubles join drain pipelining); forwarding moves to dword granule; L0 goes to dword lines. Includes the deletion list, the rv32 gate list, and the doc blast radius.
Implement docs/rv64/m1_data_tier.md: the data-memory tier becomes
aligned-dword single-beat (MemDataBits=64, 8-lane strobes, replication
write positioning) while the core stays rv32 — every widened path is
proven by the existing rv32 suites. The FLD/FSD two-phase machinery is
deleted, not generalized: phased dwords cannot serve RV64 (torn mtime,
unphaseable AMO*.D), and the un-gated size-keyed paths are exactly what
RV64 LD/SD reuse in M3.
Memory side: router/adapter/dmem/MMIO carry MemDataBits beats; the data
BRAM is one 64-bit byte-enabled BRAM at half depth initialized from a
new sw64.mem (dword-paired copy emitted next to sw.mem by every software
build backend; all loader/JTAG formats stay 32-bit-word). The CLINT's
dword-aligned mtime/mtimecmp gain single-copy-atomic 64-bit access;
UART/FIFO registers stay 32-bit-max. AMO writes present {2{result}}
with word-lane strobes derived from addr[2].
Queue side: the SQ drains every size in one beat (gen_byte_en 8-lane
via riscv_pkg::mem_strobe_for, gen_write_data replication, sq_fp64_phase
excised, DOUBLE joins the pipelined fast drain). The LQ merges its
split lo/hi data RAMs into one FLEN-wide 2-port LUTRAM keeping today's
value semantics (DOUBLE = the full beat; others = extracted value
zero-extended; NaN-boxing at CDB broadcast), deletes issued_fp64_phase,
the +4 issue leg and re-issue/phase-advance arms, un-gates the
is_fp&&DOUBLE conjuncts to size-only tests, and selects the AMO old
value from the beat by addr[2]. load_unit extracts word/half/byte from
the beat by addr[2:0]. The L0 moves to dword-granule lines with
physical-width tags (FLD becomes L0-eligible); the in-flight-fill
invalidation snoop widens to dword granule. sq_forwarding_unit's
overlap model moves to dword granule — same-dword + 8-lane mask
intersection is exact (no access crosses its beat; misaligned accesses
trap upstream), covered-subset forwarding subsumes the old case-1..3
matrix, the double_hi/word_addr_inc comparators and the extract-type
machinery are deleted, and the forwarded payload is the aligned-dword
memory image (store data shifted to its lanes). A single-beat FSD now
fires ONE store-launch invalidate, so the SQ exports is_dword and the
wrapper reservation snoop widens its compare to the dword for
dword-covering stores — exactly the coverage the old two-pulse drain
delivered (word stores keep the word-granule snoop).
Verif mirrors the bus contract end to end: config beat constants,
memory_utils 8-lane strobes + replication helpers, memory_model
dword-row init + 64-bit expected-write monitor + DUT row poke/peek
helpers, cpu_model/directed-test/wrapper-bench expected writes as
replicated beats, LQ/SQ unit benches (single-beat FLD/FSD, dword-image
forwarding, beat AMO writes; the FLD phase-reuse regression retires
with the phase machinery), cpu_tb's data memory at MemDataBits.
test_run_cocotb now fails fast on a missing program-memory image (a
dangling sw64.mem symlink previously left the data BRAM zero-filled
silently), and the yosys/riscv-tests/arch/torture runners stage
sw64.mem alongside sw.mem.
Local gate (all green, judged by PASS/FAIL text): rv32ud/rv32uf/rv32ua
riscv-tests (52/52); torture both tiers (20+20); fpu_assembly_test,
ddr_test, ddr_heap_test, ddr_atomic_test, ddr_smc_test, frost_cache
(13/13), restore_window_stress (unmodified), clint_test, isa_test,
memory_test, hello_world; directed atomics/traps/compressed;
load_queue (60/60), store_queue (53/53), tomasulo_wrapper (75/75 +
split-RS 8/8), tomasulo_test benches; LQ/SQ/L0 formal (bmc+cover)
within existing depth budgets; Verilator lint clean at rv32 and
warning-free in changed files at FROST_RV64=1; Yosys generic and
UltraScale+ synthesis; repo lint + fast Python checks. The arch F/D
compliance batches are left to CI's matrix. An independent review of
the value-semantics, forwarding-equivalence, reservation-snoop, and
L0-timing arguments found no counterexample.
Known pre-existing (unchanged by this commit): directed_multicycle and
cpu_random fail on main too — the registry marks them CLI-only, "NEEDS
PORTING to OOO"; their FLD/beat modeling is updated here so the future
port starts consistent.
…ux_boot sw64.mem Three misses the local M1 gate did not cover: - direction_predictor / prediction_metadata_tracker / control_flow_tracker unit benches elaborate their modules standalone, and since the M0 substrate their parameter defaults reference riscv_pkg::XLEN — add riscv_pkg.sv to those three file lists in tests/Makefile (M0 fallout; these targets were not in the local M0 gate). - test_data_mem_request_router still asserted 4-lane AMO strobes. The cached-AMO case (addr[2]=1) now correctly drives 0xF0; the BRAM-AMO case only passed because 0x0F equals the old 4-bit 0b1111. Both expectations are now explicit 8-lane values. - The linux_boot app Makefile (its own two-mode build, not common.mk) never produced sw64.mem, so the runner's new missing-image guard correctly refused to stage a dangling symlink in CI. Both modes now derive sw64.mem from sw.mem (in FROST_LINUX_PREBUILT=1 mode it is a pure re-encoding of the staged authoritative image), and clean targets cover it. Verified locally: all four benches pass (11/11, 6/6, 9/9, 7/7); a prebuilt-mode make derives sw64.mem from the staged image; a linux_boot smoke run boots to the 'Linux version' banner at ~2.1M cycles.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.